class Item(object):
    'Represents any item in game, should be initialised with the sequence returned by GetItem()'

    def __init__(self,game,*a):
        self.g=game
        self.__dict__.update(dict(zip(('ID','Type','Kind','ContID','X','Y','Z','Stack','Rep','Col'),a)))
        self._p=None

    @property
    def Dist(self):
        'Calculate distance from player. Note crazy UO geometry!'
        return max(abs(self.X-self.g.CharPosX),abs(self.Y-self.g.CharPosY))

    @property
    def Name(self):
        'Fetches name of the item. It is slow so is cached for multiple accesses.'
        if self._p is None:
            self._p=self.g.Property(self.ID)
        return self._p[0]

    @property
    def Prop(self):
        'Fetches properties of the item. It is slow so is cached for multiple accesses.'
        if self._p is None:
            self._p=self.g.Property(self.ID)
        return self._p[1]

    def Use(self):
        self.g.LObjectID=self.ID
        self.g.Macro(17,0,'')

class Range(object):
    def __init__(self,min,max):
        self.min=min
        self.max=max

    def __ne__(self,v):
        return v<self.min or v>self.max

class ItemsFilter(object):
    'Items filter. Note that it actually searches only when iterated, and can be reused. See Game.FindItems(...)'

    def __init__(self,game,**kw):
        self.g=game
        for k,v in kw.items():
            if isinstance(v,tuple):
                kw[k]=Range(*v)
        self.flt=kw

    def Get(self):
        try:
            return self.__iter__().next()
        except StopIteration:
            return None

    def __iter__(self):
        for a in xrange(self.g.ScanItems(False)):
            a=Item(self.g,*self.g.GetItem(a))
            for k,v in self.flt.items():
                if getattr(a,k)!=v:
                    break
            else:
                yield a
